﻿using DBUtil;
using DBUtil.Attributes;
using DotNetCommon.Extensions;
using NUnit.Framework;
using Shouldly;
using System;
using System.ComponentModel.DataAnnotations.Schema;
using System.Linq;

namespace Test.MySql.EntityInfoTests;


[TestFixture]
internal class Index : TestBase
{
    #region model
    public class BaseEntity
    {
        [PrimaryKey, Identity]
        [Column("id")]
        public virtual int Id { get; set; }
    }

    public class AuditEntity : BaseEntity
    {
        [Column("create_id")]
        public int CreateUserId { get; set; }
        [Column("create_time")]
        public DateTime CreateTime { get; set; }
        public int UpdateUserId { get; set; }
        public DateTime? UpdateTime { get; set; }
        public int DeleteUserId { get; set; }
        public DateTime? DeleteTime { get; set; }
    }

    [Table("t_person", Schema = "testdb")]
    public class PersonEntity : AuditEntity
    {
        [Column("name")]
        public string Name { get; set; }
        public int Age { get; set; }

        [JsonMap]
        public PersonExt Properties { get; set; }

        [JsonMap]
        public PersonExt Properties2 { get; set; }

        public class PersonExt
        {
            public int Score { get; set; }
            public string Addr { get; set; }
        }
    }


    [Table("t_student")]
    public class StudentEntity : AuditEntity
    {
        [PrimaryKey, Identity]
        [Column("id2")]
        public override int Id { get; set; }
        public string Name { get; set; }
    }
    #endregion

    #region model1
    public abstract class BaseEntityK<TPrimaryKey>
    {
        [Column("t_id")]
        [PrimaryKey, Identity]
        public virtual TPrimaryKey Id { get; set; }
    }
    public class PersonEntityK : BaseEntityK<int> { }
    #endregion

    [Test]
    public void NormalTest()
    {
        //BaseEntity
        var entityInfo = db.GetEntityInfo(typeof(BaseEntity));
        entityInfo.ShouldNotBeNull();

        //TableName
        entityInfo.TableName.Name.ShouldBe("BaseEntity");
        entityInfo.TableName.SchemaName.ShouldBeNull();
        entityInfo.TableName.DataBaseName.ShouldBeNull();
        entityInfo.TableName.DBLinkName.ShouldBeNull();
        entityInfo.TableName.FullNameQuoted.ShouldBe("`BaseEntity`");

        //Type信息
        entityInfo.Type.ShouldBe(typeof(BaseEntity));
        entityInfo.TypeClassFullName.ShouldBe(typeof(BaseEntity).GetClassFullName());

        //主键信息
        entityInfo.PrimaryKeyColumn.ShouldNotBeNull();
        entityInfo.PrimaryKeyColumn.PropNamePure.ShouldBe(nameof(BaseEntity.Id));

        entityInfo.Props.Count.ShouldBe(1);
        var col = entityInfo.Props[0];
        col.ShouldNotBeNull();

        #region col
        //各种Name
        col.PropNamePure.ShouldBe(nameof(BaseEntity.Id));
        col.PropNameQuoted.ShouldBe($"`{nameof(BaseEntity.Id)}`");
        col.ColumnNamePure.ShouldBe("id");
        col.ColumnNameQuoted.ShouldBe("`id`");

        //Json配置判断
        col.IsJsonMap.ShouldBeFalse();

        //SelectFunc & SelectValueFunc
        col.SelectFunc("t").ShouldBe("t.`id` `Id`");
        col.SelectFunc(null).ShouldBe("`id` `Id`");
        col.SelectValueFunc("t").ShouldBe("t.`id`");
        col.SelectValueFunc(null).ShouldBe("`id`");

        //ignore
        col.IsIgnoreInsert.ShouldBeFalse();
        col.IsIgnoreSelect.ShouldBeFalse();
        col.IsIgnoreUpdate.ShouldBeFalse();

        //主键
        col.PrimaryKeyStrategy.ShouldBe(EnumKeyStrategy.Identity);
        col.IsPrimaryKey.ShouldBeTrue();

        //枚举
        col.IsEnum.ShouldBe(false);
        col.IsFlagEnum.ShouldBe(false);

        //数据类型
        col.PropertyInfo.ShouldBe(typeof(BaseEntity).GetProperty(nameof(BaseEntity.Id)));
        col.Type.ShouldBe(typeof(int));
        col.DefaultValue.ShouldBe(default(int));
        col.TypeClassFullName.ShouldBe(typeof(int).GetClassFullName());
        col.IsNullAbleStruct.ShouldBe(false);
        col.TypeCode.ShouldBe(typeof(int).GetTypeCode());

        //其他
        col.IsColumnNameEqualPropName.ShouldBe(false);
        col.TypeName.ShouldBeNull();
        col.Order.ShouldBe(-1);
        col.IsDbString.ShouldBeNull();
        col.CanMapToTable.ShouldBe(true);
        #endregion
    }

    [Test]
    public void TestNormalAudit()
    {
        var entityInfo = db.GetEntityInfo<AuditEntity>();
        entityInfo.ShouldNotBeNull();

        // TableName
        entityInfo.TableName.Name.ShouldBe("AuditEntity");
        entityInfo.TableName.SchemaName.ShouldBeNull();
        entityInfo.TableName.DataBaseName.ShouldBeNull();
        entityInfo.TableName.DBLinkName.ShouldBeNull();
        entityInfo.TableName.FullNameQuoted.ShouldBe("`AuditEntity`");

        //Type信息
        entityInfo.Type.ShouldBe(typeof(AuditEntity));
        entityInfo.TypeClassFullName.ShouldBe(typeof(AuditEntity).GetClassFullName());

        //主键信息
        entityInfo.PrimaryKeyColumn.ShouldNotBeNull();
        entityInfo.PrimaryKeyColumn.PropNamePure.ShouldBe(nameof(AuditEntity.Id));

        EntityPropertyInfo col = null;

        #region col id 使用 BaseEntity 的
        col = entityInfo.Props.First(i => i.PropNamePure == nameof(BaseEntity.Id));
        col.ShouldNotBeNull();
        //各种Name
        col.PropNamePure.ShouldBe(nameof(BaseEntity.Id));
        col.PropNameQuoted.ShouldBe($"`{nameof(BaseEntity.Id)}`");
        col.ColumnNamePure.ShouldBe("id");
        col.ColumnNameQuoted.ShouldBe("`id`");

        //Json配置判断
        col.IsJsonMap.ShouldBeFalse();

        //SelectFunc & SelectValueFunc
        col.SelectFunc("t").ShouldBe("t.`id` `Id`");
        col.SelectFunc(null).ShouldBe("`id` `Id`");
        col.SelectValueFunc("t").ShouldBe("t.`id`");
        col.SelectValueFunc(null).ShouldBe("`id`");

        //ignore
        col.IsIgnoreInsert.ShouldBeFalse();
        col.IsIgnoreSelect.ShouldBeFalse();
        col.IsIgnoreUpdate.ShouldBeFalse();

        //主键
        col.PrimaryKeyStrategy.ShouldBe(EnumKeyStrategy.Identity);
        col.IsPrimaryKey.ShouldBeTrue();

        //枚举
        col.IsEnum.ShouldBe(false);
        col.IsFlagEnum.ShouldBe(false);

        //数据类型
        col.PropertyInfo.ShouldBe(typeof(AuditEntity).GetProperty(nameof(BaseEntity.Id)));
        col.Type.ShouldBe(typeof(int));
        col.DefaultValue.ShouldBe(default(int));
        col.TypeClassFullName.ShouldBe(typeof(int).GetClassFullName());
        col.IsNullAbleStruct.ShouldBe(false);
        col.TypeCode.ShouldBe(typeof(int).GetTypeCode());

        //其他
        col.IsColumnNameEqualPropName.ShouldBe(false);
        col.TypeName.ShouldBeNull();
        col.Order.ShouldBe(-1);
        col.IsDbString.ShouldBeNull();
        col.CanMapToTable.ShouldBe(true);
        #endregion

        #region col CreateTime
        col = entityInfo.Props.First(i => i.PropNamePure == nameof(AuditEntity.CreateTime));
        col.ShouldNotBeNull();
        //各种Name
        col.PropNamePure.ShouldBe(nameof(AuditEntity.CreateTime));
        col.PropNameQuoted.ShouldBe($"`{nameof(AuditEntity.CreateTime)}`");
        col.ColumnNamePure.ShouldBe("create_time");
        col.ColumnNameQuoted.ShouldBe("`create_time`");

        //Json配置判断
        col.IsJsonMap.ShouldBeFalse();

        //SelectFunc & SelectValueFunc
        col.SelectFunc("t").ShouldBe("t.`create_time` `CreateTime`");
        col.SelectFunc(null).ShouldBe("`create_time` `CreateTime`");
        col.SelectValueFunc("t").ShouldBe("t.`create_time`");
        col.SelectValueFunc(null).ShouldBe("`create_time`");

        //ignore
        col.IsIgnoreInsert.ShouldBeFalse();
        col.IsIgnoreSelect.ShouldBeFalse();
        col.IsIgnoreUpdate.ShouldBeFalse();

        //主键
        col.PrimaryKeyStrategy.ShouldBe(null);
        col.IsPrimaryKey.ShouldBe(false);

        //枚举
        col.IsEnum.ShouldBe(false);
        col.IsFlagEnum.ShouldBe(false);

        //数据类型
        col.PropertyInfo.ShouldBe(typeof(AuditEntity).GetProperty(nameof(AuditEntity.CreateTime)));
        col.Type.ShouldBe(typeof(DateTime));
        col.DefaultValue.ShouldBe(default(DateTime));
        col.TypeClassFullName.ShouldBe(typeof(DateTime).GetClassFullName());
        col.IsNullAbleStruct.ShouldBe(false);
        col.TypeCode.ShouldBe(typeof(DateTime).GetTypeCode());

        //其他
        col.IsColumnNameEqualPropName.ShouldBe(false);
        col.TypeName.ShouldBeNull();
        col.Order.ShouldBe(-1);
        col.IsDbString.ShouldBeNull();
        col.CanMapToTable.ShouldBe(true);
        #endregion        

        #region col CreateUserId
        col = entityInfo.Props.First(i => i.PropNamePure == nameof(AuditEntity.CreateUserId));
        col.ShouldNotBeNull();
        //各种Name
        col.PropNamePure.ShouldBe(nameof(AuditEntity.CreateUserId));
        col.PropNameQuoted.ShouldBe($"`{nameof(AuditEntity.CreateUserId)}`");
        col.ColumnNamePure.ShouldBe("create_id");
        col.ColumnNameQuoted.ShouldBe("`create_id`");

        //Json配置判断
        col.IsJsonMap.ShouldBeFalse();

        //SelectFunc & SelectValueFunc
        col.SelectFunc("t").ShouldBe("t.`create_id` `CreateUserId`");
        col.SelectFunc(null).ShouldBe("`create_id` `CreateUserId`");
        col.SelectValueFunc("t").ShouldBe("t.`create_id`");
        col.SelectValueFunc(null).ShouldBe("`create_id`");

        //ignore
        col.IsIgnoreInsert.ShouldBeFalse();
        col.IsIgnoreSelect.ShouldBeFalse();
        col.IsIgnoreUpdate.ShouldBeFalse();

        //主键
        col.PrimaryKeyStrategy.ShouldBe(null);
        col.IsPrimaryKey.ShouldBe(false);

        //枚举
        col.IsEnum.ShouldBe(false);
        col.IsFlagEnum.ShouldBe(false);

        //数据类型
        col.PropertyInfo.ShouldBe(typeof(AuditEntity).GetProperty(nameof(AuditEntity.CreateUserId)));
        col.Type.ShouldBe(typeof(int));
        col.DefaultValue.ShouldBe(default(int));
        col.TypeClassFullName.ShouldBe(typeof(int).GetClassFullName());
        col.IsNullAbleStruct.ShouldBe(false);
        col.TypeCode.ShouldBe(typeof(int).GetTypeCode());

        //其他
        col.IsColumnNameEqualPropName.ShouldBe(false);
        col.TypeName.ShouldBeNull();
        col.Order.ShouldBe(-1);
        col.IsDbString.ShouldBeNull();
        col.CanMapToTable.ShouldBe(true);
        #endregion

        #region col UpdateTime
        col = entityInfo.Props.First(i => i.PropNamePure == nameof(AuditEntity.UpdateTime));
        col.ShouldNotBeNull();
        //各种Name
        col.PropNamePure.ShouldBe(nameof(AuditEntity.UpdateTime));
        col.PropNameQuoted.ShouldBe($"`{nameof(AuditEntity.UpdateTime)}`");
        col.ColumnNamePure.ShouldBe("UpdateTime");
        col.ColumnNameQuoted.ShouldBe("`UpdateTime`");

        //Json配置判断
        col.IsJsonMap.ShouldBeFalse();

        //SelectFunc & SelectValueFunc
        col.SelectFunc("t").ShouldBe("t.`UpdateTime`");
        col.SelectFunc(null).ShouldBe("`UpdateTime`");
        col.SelectValueFunc("t").ShouldBe("t.`UpdateTime`");
        col.SelectValueFunc(null).ShouldBe("`UpdateTime`");

        //ignore
        col.IsIgnoreInsert.ShouldBeFalse();
        col.IsIgnoreSelect.ShouldBeFalse();
        col.IsIgnoreUpdate.ShouldBeFalse();

        //主键
        col.PrimaryKeyStrategy.ShouldBe(null);
        col.IsPrimaryKey.ShouldBe(false);

        //枚举
        col.IsEnum.ShouldBe(false);
        col.IsFlagEnum.ShouldBe(false);

        //数据类型
        col.PropertyInfo.ShouldBe(typeof(AuditEntity).GetProperty(nameof(AuditEntity.UpdateTime)));
        col.Type.ShouldBe(typeof(DateTime?));
        col.DefaultValue.ShouldBe(default(DateTime?));
        col.TypeClassFullName.ShouldBe(typeof(DateTime?).GetClassFullName());
        col.IsNullAbleStruct.ShouldBe(true);
        col.TypeCode.ShouldBe(typeof(DateTime).GetTypeCode());

        //其他
        col.IsColumnNameEqualPropName.ShouldBe(true);
        col.TypeName.ShouldBeNull();
        col.Order.ShouldBe(-1);
        col.IsDbString.ShouldBeNull();
        col.CanMapToTable.ShouldBe(true);
        #endregion
    }

    [Test]
    public void TestNormalStudent()
    {
        var entityInfo = db.GetEntityInfo<StudentEntity>();
        entityInfo.ShouldNotBeNull();

        // TableName
        entityInfo.TableName.Name.ShouldBe("t_student");
        entityInfo.TableName.SchemaName.ShouldBeNull();
        entityInfo.TableName.DataBaseName.ShouldBeNull();
        entityInfo.TableName.DBLinkName.ShouldBeNull();
        entityInfo.TableName.FullNameQuoted.ShouldBe("`t_student`");

        //Type信息
        entityInfo.Type.ShouldBe(typeof(StudentEntity));
        entityInfo.TypeClassFullName.ShouldBe(typeof(StudentEntity).GetClassFullName());

        //主键信息
        entityInfo.PrimaryKeyColumn.ShouldNotBeNull();
        entityInfo.PrimaryKeyColumn.PropNamePure.ShouldBe(nameof(StudentEntity.Id));

        EntityPropertyInfo col = null;

        #region col id 使用 BaseEntity 的
        col = entityInfo.Props.First(i => i.PropNamePure == nameof(BaseEntity.Id));
        col.ShouldNotBeNull();
        //各种Name
        col.PropNamePure.ShouldBe(nameof(BaseEntity.Id));
        col.PropNameQuoted.ShouldBe($"`{nameof(BaseEntity.Id)}`");
        col.ColumnNamePure.ShouldBe("id2");
        col.ColumnNameQuoted.ShouldBe("`id2`");

        //Json配置判断
        col.IsJsonMap.ShouldBeFalse();

        //SelectFunc & SelectValueFunc
        col.SelectFunc("t").ShouldBe("t.`id2` `Id`");
        col.SelectFunc(null).ShouldBe("`id2` `Id`");
        col.SelectValueFunc("t").ShouldBe("t.`id2`");
        col.SelectValueFunc(null).ShouldBe("`id2`");

        //ignore
        col.IsIgnoreInsert.ShouldBeFalse();
        col.IsIgnoreSelect.ShouldBeFalse();
        col.IsIgnoreUpdate.ShouldBeFalse();

        //主键
        col.PrimaryKeyStrategy.ShouldBe(EnumKeyStrategy.Identity);
        col.IsPrimaryKey.ShouldBeTrue();

        //枚举
        col.IsEnum.ShouldBe(false);
        col.IsFlagEnum.ShouldBe(false);

        //数据类型
        col.PropertyInfo.ShouldBe(typeof(StudentEntity).GetProperty(nameof(BaseEntity.Id)));
        col.Type.ShouldBe(typeof(int));
        col.DefaultValue.ShouldBe(default(int));
        col.TypeClassFullName.ShouldBe(typeof(int).GetClassFullName());
        col.IsNullAbleStruct.ShouldBe(false);
        col.TypeCode.ShouldBe(typeof(int).GetTypeCode());

        //其他
        col.IsColumnNameEqualPropName.ShouldBe(false);
        col.TypeName.ShouldBeNull();
        col.Order.ShouldBe(-1);
        col.IsDbString.ShouldBeNull();
        col.CanMapToTable.ShouldBe(true);
        #endregion

        #region col Name
        col = entityInfo.Props.First(i => i.PropNamePure == nameof(StudentEntity.Name));
        col.ShouldNotBeNull();
        //各种Name
        col.PropNamePure.ShouldBe(nameof(StudentEntity.Name));
        col.PropNameQuoted.ShouldBe($"`{nameof(StudentEntity.Name)}`");
        col.ColumnNamePure.ShouldBe("Name");
        col.ColumnNameQuoted.ShouldBe("`Name`");

        //Json配置判断
        col.IsJsonMap.ShouldBeFalse();

        //SelectFunc & SelectValueFunc
        col.SelectFunc("t").ShouldBe("t.`Name`");
        col.SelectFunc(null).ShouldBe("`Name`");
        col.SelectValueFunc("t").ShouldBe("t.`Name`");
        col.SelectValueFunc(null).ShouldBe("`Name`");

        //ignore
        col.IsIgnoreInsert.ShouldBeFalse();
        col.IsIgnoreSelect.ShouldBeFalse();
        col.IsIgnoreUpdate.ShouldBeFalse();

        //主键
        col.PrimaryKeyStrategy.ShouldBe(null);
        col.IsPrimaryKey.ShouldBe(false);

        //枚举
        col.IsEnum.ShouldBe(false);
        col.IsFlagEnum.ShouldBe(false);

        //数据类型
        col.PropertyInfo.ShouldBe(typeof(StudentEntity).GetProperty(nameof(StudentEntity.Name)));
        col.Type.ShouldBe(typeof(string));
        col.DefaultValue.ShouldBe(default(string));
        col.TypeClassFullName.ShouldBe(typeof(string).GetClassFullName());
        col.IsNullAbleStruct.ShouldBe(false);
        col.TypeCode.ShouldBe(typeof(string).GetTypeCode());

        //其他
        col.IsColumnNameEqualPropName.ShouldBe(true);
        col.TypeName.ShouldBeNull();
        col.Order.ShouldBe(-1);
        col.IsDbString.ShouldBeNull();
        col.CanMapToTable.ShouldBe(true);
        #endregion

        #region col CreateTime
        col = entityInfo.Props.First(i => i.PropNamePure == nameof(StudentEntity.CreateTime));
        col.ShouldNotBeNull();
        //各种Name
        col.PropNamePure.ShouldBe(nameof(StudentEntity.CreateTime));
        col.PropNameQuoted.ShouldBe($"`{nameof(StudentEntity.CreateTime)}`");
        col.ColumnNamePure.ShouldBe("create_time");
        col.ColumnNameQuoted.ShouldBe("`create_time`");

        //Json配置判断
        col.IsJsonMap.ShouldBeFalse();

        //SelectFunc & SelectValueFunc
        col.SelectFunc("t").ShouldBe("t.`create_time` `CreateTime`");
        col.SelectFunc(null).ShouldBe("`create_time` `CreateTime`");
        col.SelectValueFunc("t").ShouldBe("t.`create_time`");
        col.SelectValueFunc(null).ShouldBe("`create_time`");

        //ignore
        col.IsIgnoreInsert.ShouldBeFalse();
        col.IsIgnoreSelect.ShouldBeFalse();
        col.IsIgnoreUpdate.ShouldBeFalse();

        //主键
        col.PrimaryKeyStrategy.ShouldBe(null);
        col.IsPrimaryKey.ShouldBe(false);

        //枚举
        col.IsEnum.ShouldBe(false);
        col.IsFlagEnum.ShouldBe(false);

        //数据类型
        col.PropertyInfo.ShouldBe(typeof(StudentEntity).GetProperty(nameof(StudentEntity.CreateTime)));
        col.Type.ShouldBe(typeof(DateTime));
        col.DefaultValue.ShouldBe(default(DateTime));
        col.TypeClassFullName.ShouldBe(typeof(DateTime).GetClassFullName());
        col.IsNullAbleStruct.ShouldBe(false);
        col.TypeCode.ShouldBe(typeof(DateTime).GetTypeCode());

        //其他
        col.IsColumnNameEqualPropName.ShouldBe(false);
        col.TypeName.ShouldBeNull();
        col.Order.ShouldBe(-1);
        col.IsDbString.ShouldBeNull();
        col.CanMapToTable.ShouldBe(true);
        #endregion        
    }

    [Test]
    public void TestNormalPerson()
    {
        var entityInfo = db.GetEntityInfo<PersonEntity>();
        entityInfo.ShouldNotBeNull();

        // TableName
        entityInfo.TableName.Name.ShouldBe("t_person");
        entityInfo.TableName.SchemaName.ShouldBe("testdb");
        entityInfo.TableName.DataBaseName.ShouldBe("testdb");
        entityInfo.TableName.DBLinkName.ShouldBeNull();
        entityInfo.TableName.FullNameQuoted.ShouldBe("`testdb`.`t_person`");

        //Type信息
        entityInfo.Type.ShouldBe(typeof(PersonEntity));
        entityInfo.TypeClassFullName.ShouldBe(typeof(PersonEntity).GetClassFullName());

        //主键信息
        entityInfo.PrimaryKeyColumn.ShouldNotBeNull();
        entityInfo.PrimaryKeyColumn.PropNamePure.ShouldBe(nameof(PersonEntity.Id));

        EntityPropertyInfo col = null;

        #region col id 使用 BaseEntity 的
        col = entityInfo.Props.First(i => i.PropNamePure == nameof(BaseEntity.Id));
        col.ShouldNotBeNull();
        //各种Name
        col.PropNamePure.ShouldBe(nameof(BaseEntity.Id));
        col.PropNameQuoted.ShouldBe($"`{nameof(BaseEntity.Id)}`");
        col.ColumnNamePure.ShouldBe("id");
        col.ColumnNameQuoted.ShouldBe("`id`");

        //Json配置判断
        col.IsJsonMap.ShouldBeFalse();

        //SelectFunc & SelectValueFunc
        col.SelectFunc("t").ShouldBe("t.`id` `Id`");
        col.SelectFunc(null).ShouldBe("`id` `Id`");
        col.SelectValueFunc("t").ShouldBe("t.`id`");
        col.SelectValueFunc(null).ShouldBe("`id`");

        //ignore
        col.IsIgnoreInsert.ShouldBeFalse();
        col.IsIgnoreSelect.ShouldBeFalse();
        col.IsIgnoreUpdate.ShouldBeFalse();

        //主键
        col.PrimaryKeyStrategy.ShouldBe(EnumKeyStrategy.Identity);
        col.IsPrimaryKey.ShouldBeTrue();

        //枚举
        col.IsEnum.ShouldBe(false);
        col.IsFlagEnum.ShouldBe(false);

        //数据类型
        col.PropertyInfo.ShouldBe(typeof(PersonEntity).GetProperty(nameof(BaseEntity.Id)));
        col.Type.ShouldBe(typeof(int));
        col.DefaultValue.ShouldBe(default(int));
        col.TypeClassFullName.ShouldBe(typeof(int).GetClassFullName());
        col.IsNullAbleStruct.ShouldBe(false);
        col.TypeCode.ShouldBe(typeof(int).GetTypeCode());

        //其他
        col.IsColumnNameEqualPropName.ShouldBe(false);
        col.TypeName.ShouldBeNull();
        col.Order.ShouldBe(-1);
        col.IsDbString.ShouldBeNull();
        col.CanMapToTable.ShouldBe(true);
        #endregion

        #region col Properties [JsonMap]
        col = entityInfo.Props.First(i => i.PropNamePure == nameof(PersonEntity.Properties));
        col.ShouldNotBeNull();
        //各种Name
        col.PropNamePure.ShouldBe(nameof(PersonEntity.Properties));
        col.PropNameQuoted.ShouldBe($"`{nameof(PersonEntity.Properties)}`");
        col.ColumnNamePure.ShouldBe("Properties");
        col.ColumnNameQuoted.ShouldBe("`Properties`");

        //Json配置判断
        col.IsJsonMap.ShouldBe(true);

        //SelectFunc & SelectValueFunc
        col.SelectFunc("t").ShouldBe("t.`Properties`");
        col.SelectFunc(null).ShouldBe("`Properties`");
        col.SelectValueFunc("t").ShouldBe("t.`Properties`");
        col.SelectValueFunc(null).ShouldBe("`Properties`");

        //ignore
        col.IsIgnoreInsert.ShouldBeFalse();
        col.IsIgnoreSelect.ShouldBeFalse();
        col.IsIgnoreUpdate.ShouldBeFalse();

        //主键
        col.PrimaryKeyStrategy.ShouldBe(null);
        col.IsPrimaryKey.ShouldBe(false);

        //枚举
        col.IsEnum.ShouldBe(false);
        col.IsFlagEnum.ShouldBe(false);

        //数据类型
        col.PropertyInfo.ShouldBe(typeof(PersonEntity).GetProperty(nameof(PersonEntity.Properties)));
        col.Type.ShouldBe(typeof(PersonEntity.PersonExt));
        col.DefaultValue.ShouldBe(default(PersonEntity.PersonExt));
        col.TypeClassFullName.ShouldBe(typeof(PersonEntity.PersonExt).GetClassFullName());
        col.IsNullAbleStruct.ShouldBe(false);
        col.TypeCode.ShouldBe(typeof(PersonEntity.PersonExt).GetTypeCode());

        //其他
        col.IsColumnNameEqualPropName.ShouldBe(true);
        col.TypeName.ShouldBeNull();
        col.Order.ShouldBe(-1);
        col.IsDbString.ShouldBeNull();
        col.CanMapToTable.ShouldBe(true);
        #endregion

        #region col Properties2 [JsonMap]
        col = entityInfo.Props.First(i => i.PropNamePure == nameof(PersonEntity.Properties2));
        col.ShouldNotBeNull();
        //各种Name
        col.PropNamePure.ShouldBe(nameof(PersonEntity.Properties2));
        col.PropNameQuoted.ShouldBe($"`{nameof(PersonEntity.Properties2)}`");
        col.ColumnNamePure.ShouldBe("Properties2");
        col.ColumnNameQuoted.ShouldBe("`Properties2`");

        //Json配置判断
        col.IsJsonMap.ShouldBe(true);

        //SelectFunc & SelectValueFunc
        col.SelectFunc("t").ShouldBe("t.`Properties2`");
        col.SelectFunc(null).ShouldBe("`Properties2`");
        col.SelectValueFunc("t").ShouldBe("t.`Properties2`");
        col.SelectValueFunc(null).ShouldBe("`Properties2`");

        //ignore
        col.IsIgnoreInsert.ShouldBeFalse();
        col.IsIgnoreSelect.ShouldBeFalse();
        col.IsIgnoreUpdate.ShouldBeFalse();

        //主键
        col.PrimaryKeyStrategy.ShouldBe(null);
        col.IsPrimaryKey.ShouldBe(false);

        //枚举
        col.IsEnum.ShouldBe(false);
        col.IsFlagEnum.ShouldBe(false);

        //数据类型
        col.PropertyInfo.ShouldBe(typeof(PersonEntity).GetProperty(nameof(PersonEntity.Properties2)));
        col.Type.ShouldBe(typeof(PersonEntity.PersonExt));
        col.DefaultValue.ShouldBe(default(PersonEntity.PersonExt));
        col.TypeClassFullName.ShouldBe(typeof(PersonEntity.PersonExt).GetClassFullName());
        col.IsNullAbleStruct.ShouldBe(false);
        col.TypeCode.ShouldBe(typeof(PersonEntity.PersonExt).GetTypeCode());

        //其他
        col.IsColumnNameEqualPropName.ShouldBe(true);
        col.TypeName.ShouldBeNull();
        col.Order.ShouldBe(-1);
        col.IsDbString.ShouldBeNull();
        col.CanMapToTable.ShouldBe(true);
        #endregion
    }

    [Test]
    public void TestGenericBase()
    {
        var entityInfo = db.GetEntityInfo<PersonEntityK>();
        entityInfo.ShouldNotBeNull();
        entityInfo.Props.ShouldNotBeEmpty();
        entityInfo.Props[0].PropNamePure.ShouldBe(nameof(PersonEntityK.Id));
        entityInfo.Props[0].ColumnNameQuoted.ShouldBe("`t_id`");
        entityInfo.Props[0].PrimaryKeyStrategy.ShouldBe(EnumKeyStrategy.Identity);
    }
}
